#ifndef _QUEUE_H
#define _QUEUE_H

/*
 * Tipo de datos: queueT
 * ---------------------
 * Estructura que encapsula los campos que utiliza la cola circular.
 */
typedef struct {
	void *array; /* arreglo donde se almacenan los elementos de la cola */
	unsigned int dim; /* cantidad de elementos que entran en array */
	unsigned int size; /* tamaño de los elementos de la cola */
	unsigned int head; /* cabeza de la cola */
	unsigned int tail; /* final de la cola */
} queueT;



/*
 * Funcion: new_queue
 * ------------------
 * Devuelve una nueva estructura de cola circular queueT, con sus campos
 * debidamente inicializados.
 * Recibe el puntero a una zona de memoria ya reservada para la cola, su
 * dimension dim y el tamaño de los elementos size.
 * La dimension dim debe ser la cantidad de posiciones disponibles en el
 * arreglo para copiar elementos, pero se pueden encolar hasta dim - 1
 * elementos.
 */
queueT
new_queue(void *array, unsigned int dim, unsigned int size);

/*
 * Funcion: enqueue
 * ----------------
 * Encola un elemento apuntado por element, copiandolo al final de la cola
 * circular e incrementando el final de la cola circularmente.
 * Se evalua como falso si no se puede encolar porque la cola esta llena,
 * o como verdadero en caso contrario.
 */
int
enqueue(queueT *q, void *element);

/*
 * Funcion: enqueue
 * ----------------
 * Desencola un elemento de la cola circular q, copiandolo en el elemento
 * apuntado por element e incrementando la cabeza de la cola circularmente.
 * Se evalua como falso si no se puede desencolar porque la cola esta vacia,
 * o como verdadero en caso contrario.
 */
int
dequeue(queueT *q, void *element);

/*
 * Funcion: queue_is_empty
 * -----------------------
 * Devuelve un booleano que indica si la cola circular esta vacia.
 */
int
queue_is_empty(queueT *q);

/*
 * Funcion: queue_is_full
 * ----------------------
 * Devuelve un booleano que indica si la cola circular esta llena.
 */
int
queue_is_full(queueT *q);

/*
 * Funcion: queue_length
 * ---------------------
 * Devuelve un la cantidad de elementos encolados en la cola circular.
 */
unsigned int
queue_length(queueT *q);

/*
 * Funcion: get_queue_element
 * --------------------------
 * Copia en el elemento apuntado por element el i-esimo elemento encolado en
 * la cola circular.
 * Se evalua como falso si no se puede copiar el elemento porque el indice i
 * esta fuera de rango, o como verdadero en caso contrario.
 */
int
get_queue_element(queueT *q, void *element, unsigned int i);

/*
 * Funcion: get_queue_next_index
 * -----------------------------
 * Incrementa el indice i de manera que se puedan recorrer circularmente los
 * elementos de la cola circular (round-robin), sin salirse de rango.
 */
unsigned int
get_queue_next_index(queueT *q, unsigned int i);


#endif /* _QUEUE_H */

